package com.ext.aic.components;

import android.annotation.SuppressLint;
import android.content.Context;
import android.view.View;

import androidx.annotation.IdRes;

import com.bigkoo.wheelview.listener.OnItemSelectedListener;
import com.bigkoo.wheelview.view.WheelView;
import com.ext.aic.AICManager;
import com.ext.aic.R;
import com.ext.aic.adapter.PeriodOfHostingAdapter;
import com.ext.aic.beans.HostingTimeItem;
import com.ext.aic.beans.HostingTimeItem_;
import com.ext.aic.beans.PeriodOptionItem;
import com.ext.aic.constants.EBusConstants;
import com.ext.aic.utils.LoadingUtils;
import com.ext.aic.utils.ToastyUtils;
import com.ext.aic.utils.device.DeviceUtils;
import com.eyinfo.android_pure_utils.ebus.EBus;
import com.eyinfo.android_pure_utils.utils.ObjectJudge;
import com.eyinfo.android_pure_utils.utils.PixelUtils;
import com.lxj.xpopup.core.BottomPopupView;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import io.objectbox.query.QueryBuilder;

@SuppressLint("ViewConstructor")
public class PeriodOfHostingBottomPopup extends BottomPopupView {
    private HostingTimeItem hostingTimeItem;
    private int startHour, startMinute, endHour, endMinute;
    private Context context;

    public PeriodOfHostingBottomPopup(Context context, HostingTimeItem hostingTimeItem) {
        super(context);
        this.context = context;
        this.hostingTimeItem = hostingTimeItem;
    }

    @Override
    protected int getImplLayoutId() {
        return R.layout.period_of_hosting_select_layout;
    }

    @Override
    protected int getMaxHeight() {
        return PixelUtils.dip2px(getContext(), 280);
    }

    @Override
    protected void onCreate() {
        bindWheelAdapter(R.id.start_hour_wv, getHourItems());
        bindWheelAdapter(R.id.start_minute_wv, getMinuteItems());
        bindWheelAdapter(R.id.end_hour_wv, getHourItems());
        bindWheelAdapter(R.id.end_minute_wv, getMinuteItems());

        findViewById(R.id.cancel_btn).setOnClickListener(this::onCancelClick);
        findViewById(R.id.confirm_btn).setOnClickListener(this::onConfirmClick);
    }

    public void onCancelClick(View view) {
        dismiss();
    }

    public void onConfirmClick(View view) {
        if (startHour == 0 || startMinute == 0) {
            ToastyUtils.getInstance().show(context.getString(R.string.select_start_time_hint));
            return;
        }
        if (endHour == 0 || endMinute == 0) {
            ToastyUtils.getInstance().show(context.getString(R.string.select_end_time_hint));
            return;
        }
        if (startHour > endHour || (startHour == endHour && startMinute > endMinute)) {
            ToastyUtils.getInstance().show(context.getString(R.string.select_min_time_exceed_hint));
            return;
        }
        int start = startHour * 60 + startMinute;
        int end = endHour * 60 + endMinute;
        int diff = end - start;
        if (diff < 5) {
            ToastyUtils.getInstance().show(context.getString(R.string.select_time_min_hint));
            return;
        }
        if (!checkRepeatTimeSlot()) {
            ToastyUtils.getInstance().show(context.getString(R.string.select_time_repeat_hint));
            return;
        }
        EBus.getInstance().post(EBusConstants.selectHostingTime, startHour, startMinute, endHour, endMinute);
        dismiss();
    }

    private boolean checkRepeatTimeSlot() {
        LoadingUtils.showLoading(context, R.string.processing);
        List<HostingTimeItem> list = AICManager.getInstance().findList(HostingTimeItem.class, timeItem -> {
            String deviceId = DeviceUtils.getInstance().getDeviceId(context);
            timeItem.equal(HostingTimeItem_.deviceId, deviceId, QueryBuilder.StringOrder.CASE_INSENSITIVE);
        });
        if (ObjectJudge.isNullOrEmpty(list)) {
            LoadingUtils.hideLoading();
            return true;
        }
        for (HostingTimeItem timeItem : list) {
            if (hasTimeSlot(timeItem)) {
                return false;
            }
        }
        return true;
    }

    private boolean hasTimeSlot(HostingTimeItem timeItem) {
        int start = timeItem.getStartHour() * 60 + timeItem.getStartMinute();
        int preStart = startHour * 60 + startMinute;
        int end = timeItem.getEndHour() * 60 + timeItem.getEndMinute();
        int preEnd = endHour * 60 + endMinute;
        return start < preEnd && end > preStart;
    }

    private void bindWheelAdapter(@IdRes int id, List<PeriodOptionItem> optionItems) {
        WheelView wheelView = findViewById(id);
        int currentItem = getCurrentItem(id, optionItems);
        if (currentItem >= 0) {
            wheelView.setCurrentItem(currentItem);
        }
        wheelView.setAdapter(new PeriodOfHostingAdapter(optionItems));
        wheelView.setOnItemSelectedListener(new WheelItemSelected(id, optionItems));
        setWheelProperty(wheelView);
    }

    private int getCurrentItem(int id, List<PeriodOptionItem> optionItems) {
        Calendar calendar = Calendar.getInstance();
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        if (id == R.id.start_hour_wv) {
            startHour = hostingTimeItem == null ? hour : hostingTimeItem.getStartHour();
            return findIndex(optionItems, startHour);
        } else if (id == R.id.start_minute_wv) {
            startMinute = hostingTimeItem == null ? minute : hostingTimeItem.getStartMinute();
            return findIndex(optionItems, startMinute);
        } else if (id == R.id.end_hour_wv) {
            endHour = hostingTimeItem == null ? hour : hostingTimeItem.getEndHour();
            return findIndex(optionItems, endHour);
        } else if (id == R.id.end_minute_wv) {
            endMinute = hostingTimeItem == null ? minute : hostingTimeItem.getEndMinute();
            return findIndex(optionItems, endMinute);
        }
        return -1;
    }

    private int findIndex(List<PeriodOptionItem> optionItems, int value) {
        int size = optionItems.size();
        for (int i = 0; i < size; i++) {
            PeriodOptionItem optionItem = optionItems.get(i);
            if (optionItem.getValue() == value) {
                return i;
            }
        }
        return -1;
    }

    private class WheelItemSelected implements OnItemSelectedListener {

        private int resId;
        private List<PeriodOptionItem> optionItems;

        public WheelItemSelected(int resId, List<PeriodOptionItem> optionItems) {
            this.resId = resId;
            this.optionItems = optionItems;
        }

        @Override
        public void onItemSelected(int position) {
            PeriodOptionItem optionItem = optionItems.get(position);
            if (resId == R.id.start_hour_wv) {
                startHour = optionItem.getValue();
            } else if (resId == R.id.start_minute_wv) {
                startMinute = optionItem.getValue();
            } else if (resId == R.id.end_hour_wv) {
                endHour = optionItem.getValue();
            } else if (resId == R.id.end_minute_wv) {
                endMinute = optionItem.getValue();
            }
        }
    }

    private void setWheelProperty(WheelView wheelView) {
        wheelView.setCyclic(true);
        wheelView.setTextColorOut(0xE6BFBFBF);
        wheelView.setTextSize(18);
        wheelView.setTextColorCenter(0xff3FB2FF);
        wheelView.setItemsVisibleCount(5);
    }

    private List<PeriodOptionItem> getHourItems() {
        List<PeriodOptionItem> items = new ArrayList<>();
        for (int i = 0; i < 24; i++) {
            items.add(new PeriodOptionItem(i < 10 ? String.format("0%s", i) : String.valueOf(i), i));
        }
        return items;
    }

    private List<PeriodOptionItem> getMinuteItems() {
        List<PeriodOptionItem> items = new ArrayList<>();
        for (int i = 1; i < 60; i++) {
            items.add(new PeriodOptionItem(i < 10 ? String.format("0%s", i) : String.valueOf(i), i));
        }
        return items;
    }
}
